/*
Project Name : Menfram
Module Name  : Menfram
Date  : 07/06/2013
responsible : Mateus Neto
Obs  : The license of this software is Mozilla Public License 1.1 
contact : mentrixmax@gmail.com
*/


using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Collections;
using Menfram.Business.Interface;
using Menfram.DAL.Interface;
using Menfram.Entity.Interface;
using Menfram.Common.Exceptions;
using System.Data.Common;

namespace Menfram.Business.Abstract
{

    /// <summary>
    /// Class responsability of the Logic Business 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class AbstractBusiness<T> : IBusiness<T>
    {

        #region Atributes
        /// <summary>
        /// Thre Transaction
        /// </summary>
        protected DbTransaction transaction = null;
        #endregion

        #region Abstratos
            /// <summary>
            /// this method must return the Correct DAO
            /// </summary>
            /// <returns></returns>
            public abstract IDAL<T> getDAO();
            
            /// <summary>
            ///  The Method valid the Create
            /// </summary>
            /// <param name="e"></param>
            /// <returns></returns>
            public  abstract bool validaCreate(T e);

            /// <summary>
            /// The Method valid the Update
            /// </summary>
            /// <param name="e"></param>
            /// <returns></returns>
            public abstract bool validaUpdate(T e);


            /// <summary>
            /// The method valid the delete
            /// </summary>
            /// <param name="e"></param>
            /// <returns></returns>
            public virtual bool validaRemove(int? id)
            {
                return true;
            }

        #endregion

        #region Method Public;

        /// <summary>
            /// just call the getFirst in the dao
        /// </summary>
        /// <returns></returns>
        public T getFirst()
        {
            T entidade ;
            try
            {
                entidade = getDAO().getFirst();
            }
            catch (SqlException exp)
            {
                throw Exceptions.encapsulatesException(exp);
            }
            catch (Exception e)
            {
                
                throw e;
            }
            return entidade;
        }

        /// <summary>
        /// <summary>
        /// just call the getLast in the dao
        /// </summary>
        /// <returns></returns>
        public T getLast()
        {
            T entidade ;
            try
            {
                entidade = getDAO().getLast();
            }
            catch (SqlException exp) {
                throw Exceptions.encapsulatesException(exp);
            }

            catch (Exception e)
            {

                throw e;
            }
            return entidade;
        }

       
        /// <summary>
        /// just call the getNext in the dao
        /// </summary>
        /// <param name="KeyCurrent"></param>
        /// <param name="SequenceCurrent"></param>
        /// <returns></returns>
        public T getNext(string KeyCurrent, string SequenceCurrent)
        {
            T proximo ;
            try
            {
                proximo = getDAO().getNext(KeyCurrent, SequenceCurrent);
            }
            catch (SqlException exp)
            {
                throw Exceptions.encapsulatesException(exp);
            }
            catch (Exception e)
            {

                throw e;
            }
            return proximo;
        }

      
        /// <summary>
        ///  just call the findByKey in the dao
        /// </summary>
        /// <param name="KeyCurrent"></param>
        /// <param name="SequenceCurrent"></param>
        /// <returns></returns>
        public T getPrior(string KeyCurrent, string SequenceCurrent)
        {
            T anterior ;
            try
            {
                anterior = getDAO().getPrior(KeyCurrent, SequenceCurrent);
            }
            catch (SqlException exp)
            {
                throw Exceptions.encapsulatesException(exp);
            }
            catch (Exception e)
            {
                throw e;
            }
            return anterior;
        }

     
    
        /// <summary>
        ///  just call the findByKey in the dao
        /// </summary>
        /// <param name="chave"></param>
        /// <returns></returns>
        public T findByKey(string chave)
        {
            T findChave ;
            try
            {
                findChave = getDAO().findByKey(chave);
            }
            catch (SqlException exp)
            {
                throw Exceptions.encapsulatesException(exp);
            }
            catch (Exception e)
            {

                throw e;
            }
            return findChave;
        }

        /// <summary>
        ///  just call the findAll in the dao
        /// </summary>
        /// <returns></returns>
        public IList<T> findAll()
        {
            IList<T> retorno = null;
            try
            {
                retorno = getDAO().findAll();
            }
            catch(SqlException exp){
                throw Exceptions.encapsulatesException(exp);
            }
            catch (Exception e)
            {
               throw e;
            }
            return retorno;
        }

       

        /// <summary>
        ///   just call the findByParameters in the dao
        /// </summary>
        /// <param name="entidade"></param>
        /// <returns></returns>
        public virtual IList<T> findByParameters(T entidade)
        {
            IList<T> retorno = null;
            try
            {
                retorno = getDAO().findByParameters(entidade);
            }
            catch (SqlException exp)
            {
                throw Exceptions.encapsulatesException(exp);
            }
            catch (Exception e)
            {
                throw e;
            }
            return retorno;
        }

        /// <summary>
        ///  just call the update in the dao
        /// </summary>
        /// <param name="entidade"></param>
        /// <returns></returns>
        public virtual bool update(T entidade)
        {
            bool retorno = false;
            try
            {
                if (validaUpdate(entidade))
                {
                    retorno =  getDAO().update(entidade);
                }
            }
            catch (SqlException exp)
            {
                throw Exceptions.encapsulatesException(exp);
            }
            catch (Exception e){
                throw e;
            }
            return retorno;
        }

        /// <summary>
        ///  just call the create in the dao
        /// </summary>
        /// <param name="entidade"></param>
        /// <returns></returns>
        public virtual bool create(T entidade)
        {
            bool retorno = false;
            try
            {
                if (validaCreate(entidade))
                {
                    IDAL<T> dao = getDAO();
                    retorno =  dao.create(entidade);
                    IEntity setSrequence = (IEntity)entidade;
                    setSrequence.Sequencial = getId(entidade);
                }
            }
            catch (SqlException exp)
            {
                throw Exceptions.encapsulatesException(exp);
            }
            catch (Exception e){ 
                 throw e;
            }
            return retorno;
        }

        /// <summary>
        ///  just call the delete in the dao
        /// </summary>
        /// <param name="entidade"></param>
        /// <returns></returns>
        public virtual bool delete(int? id)
        {
            bool retorno = false;
            try
            {
                if (validaRemove(id))
                {
                    retorno = getDAO().delete(id);
                }
            }

            catch (SqlException e) {
                throw Exceptions.encapsulatesException(e);
            }
            catch (Exception e)
            {
                throw e;
            }
            return retorno;
        }

        /// <summary>
        ///  just call the findById in the dao;
        /// </summary>
        /// <param name="Sequencial"></param>
        /// <returns></returns>
        public T findById(int? Sequencial)
        {
            T retorno ;
            try
            {
                if (Sequencial == null)
                {
                    retorno = default(T);
                    return retorno;
                }
                retorno = getDAO().findById(Sequencial);
            }
            catch (SqlException exp)
            {
                throw Exceptions.encapsulatesException(exp);
            }
            catch (Exception e){
                throw e;
            }
            return retorno;
        }

      

        
        /// <summary>
        /// just call the getId in the dao;
        /// </summary>
        /// <param name="entidade"></param>
        /// <returns></returns>
        public int? getId(T entidade)
        {
            int? retorno = null;
            try
            {
                retorno = getDAO().getId(entidade);
            }
            catch (SqlException exp)
            {
                throw Exceptions.encapsulatesException(exp);
            }
            catch (Exception e)
            {   
                throw e;
            }
            return retorno;
        }

        #endregion
    }
}
